package com.uuj.project.net;

import com.uuj.project.base.BaseResponse;
import com.uuj.project.listener.NetResultCallBack;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subscribers.ResourceSubscriber;

/**
 * ProjectName:    ok_rxjava_retrofit
 * Package:        com.uuj.project.net
 * ClassName:      NetController
 * Description:    网络请求处理
 * Author:         张继
 * CreateDate:     2019/9/29 10:03
 * UpdateUser:     更新者
 * UpdateDate:     2019/9/29 10:03
 * UpdateRemark:   更新说明
 * Version:        1.0
 */
public final class NetController<T> {

    private Map<String, CompositeDisposable> map = null;
    private static NetController controller = null;

    public static NetController getInstance() {
        if (controller == null) {
            synchronized (NetController.class) {
                if (controller == null) {
                    controller = new NetController();
                }
            }
        }
        return controller;
    }

    private NetController() {
    }

    /**
     * 请求网络
     *
     * @param tClass     class
     * @param flowable   api接口
     * @param subscriber 订阅
     */
    public void netServer(Class<T> tClass, Flowable<BaseResponse<T>> flowable, ResourceSubscriber subscriber) {
        addSubscription(tClass, flowable.compose(RxUtil.applySchedulers())
                .compose(RxUtil.handleResult())
                .subscribeWith(subscriber));
    }

    /**
     * 请求网络
     *
     * @param flowable   api接口
     * @param subscriber 订阅
     */
    public Disposable netServerDelay(Class<T> tClass, Flowable<BaseResponse<T>> flowable, NetResultCallBack<BaseResponse<T>> subscriber) {
        long nowTime = System.currentTimeMillis();
        int delay = 5;
        return flowable.doOnSubscribe(subscription -> {
            if (System.currentTimeMillis() - nowTime > 45 * 1000) {
                subscription.cancel();
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(tBaseResponse -> {
                    subscriber.success(tBaseResponse);
                })
                .delay(delay, TimeUnit.SECONDS, true)// 设置delayError为true，表示出现错误的时候也需要延迟5s进行通知，达到无论是请求正常还是请求失败，都是5s后重新订阅，即重新请求。
                .repeat()
                .retry()
                .subscribe();
    }


    /**
     * 保存订阅后的disposable
     *
     * @param tClass     class
     * @param disposable 实例对象
     */
    public void addSubscription(Class<T> tClass, Disposable disposable) {
        if (map == null) {
            map = new HashMap<>();
        }
        String key = tClass.getName();
        if (map.get(key) != null) {
            map.get(key).add(disposable);
        } else {
            //一次性容器,可以持有多个并提供 添加和移除。
            CompositeDisposable disposables = new CompositeDisposable();
            disposables.add(disposable);
            map.put(key, disposables);
        }
    }

    /**
     * 取消订阅
     *
     * @param tClass 类型
     */
    public void unSubscribe(Class<T> tClass) {
        if (map == null) {
            return;
        }
        String key = tClass.getName();
        if (!map.containsKey(key)) {
            return;
        }
        if (map.get(key) != null) {
            map.get(key).dispose();
            map.get(key).clear();
        }
        map.remove(key);
    }
}
